fn main() {
    let str = String::from("a");
    let a = Some(str);
    // 获取所有权
    let str: String = a.unwrap();
    let mut a = Some(str);
    //
    let str: Option<&mut String> = a.as_mut();
    assert_eq!(str.unwrap(), "a");
    //  所有权没有转移
    assert_eq!(a.as_mut().unwrap(), "a");
    //  注释的代码编译不过，因为str是一个独立的对象，依然遵循所有权规则。
    // 不过str中对数据是借阅，而非获取所有权。所以不影响a的所有权。
    //  assert_eq!(str.as_mut().unwrap(),"a");
    assert_eq!(a.as_ref().unwrap_or(&"b".to_string()), "a");
    let mut str = Some(Box::new("a".to_string()));
    // 先做借阅变换，然后对内部数据做解引用变换
    let a: Option<&String> = str.as_deref();
    let a: Option<&mut String> = str.as_deref_mut();
    if let Some(a) = &mut str {
        //  因为match是借阅方式，所以a也只能是借阅方式，而非拥有。
        let a: &mut Box<String> = a;
    }
    if let Some(a) = str {
        //因为match是所有权转移方式，所以str已经被消费掉了，不可以再用
        let a: Box<String> = a;
    }

    let mut str = Some("a".to_string());
    let mut a = None;
    str.map(|it| {
        //  注释里的代码有问题，因为map使用的是所有权转移，所以此时str已经无效了
        // str = Some(it);
        a = Some(it);
    });
    str = a;

    str.take().map(|it| {
        //  take获取str内部的数据，并将str置为None，所以str此时没有未完成的修改动作，所以可以对下面str做重新赋值。
        // 通过有无take()的对比。可知，修改有实际分两种，一是对局部数据的改动，一是对整体数据的重新赋值。
        str = Some(it)
    });
}
